package org.alicuu.toolkit;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Created by IntelliJ IDEA.
 * User: Danny
 * Date: 16/07/06
 * Time: 10:26
 */
public class ReflectUtil {

    /**
     * invoke setter method of an object
     */
    public static Object invokeGetter(String fieldName, Object object) {
        try {
            Class<?> clazz = object.getClass();
            Method method = clazz.getDeclaredMethod("get" + StringUtil.firstCharUpperCase(fieldName), null);
            return method.invoke(object, null);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void invokeSetter(Object rowObj, String fieldName, Object fieldValue) {
        try {
            Class clazz = rowObj.getClass();
            Method m = clazz.getDeclaredMethod("set" + StringUtil.firstCharUpperCase(fieldName), fieldValue.getClass());
            m.invoke(rowObj, fieldValue);
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }


    public static Object invokeMethod(Object bean, Method method, Object... args) {
        try {
            Class<?>[] types = method.getParameterTypes();
            int argCount = args == null ? 0 : args.length;

            if (argCount != types.length)
                throw new RuntimeException(method.getName() + " in " + bean);

            for (int i = 0; i < argCount; i++)
                args[i] = cast(args[i], types[i]);

            return method.invoke(bean, args);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }

        return null;
    }

    private static <T> T cast(Object value, Class<T> type) {
        if (value != null && !type.isAssignableFrom(value.getClass())) {
            if (is(type, int.class, Integer.class)) {
                value = Integer.parseInt(String.valueOf(value));
            } else if (is(type, long.class, Long.class)) {
                value = Long.parseLong(String.valueOf(value));
            } else if (is(type, float.class, Float.class)) {
                value = Float.parseFloat(String.valueOf(value));
            } else if (is(type, double.class, Double.class)) {
                value = Double.parseDouble(String.valueOf(value));
            } else if (is(type, boolean.class, Boolean.class)) {
                value = Boolean.parseBoolean(String.valueOf(value));
            } else if (is(type, String.class)) {
                value = String.valueOf(value);
            }
        }
        return (T) value;
    }

    /**
     * 对象是否其中一个
     */
    public static boolean is(Object obj, Object... maybe) {
        if (obj != null && maybe != null) {
            for (Object mb : maybe)
                if (obj.equals(mb))
                    return true;
        }
        return false;
    }

}
